/******************************************************************************
 * Product: Adempiere ERP & CRM Smart Business Solution                        *
 * Copyright (C) 1999-2006 ComPiere, Inc. All Rights Reserved.                *
 * This program is free software; you can redistribute it and/or modify it    *
 * under the terms version 2 of the GNU General Public License as published   *
 * by the Free Software Foundation. This program is distributed in the hope   *
 * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied *
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.           *
 * See the GNU General Public License for more details.                       *
 * You should have received a copy of the GNU General Public License along    *
 * with this program; if not, write to the Free Software Foundation, Inc.,    *
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.                     *
 * For the text or an alternative of this public license, you may reach us    *
 * ComPiere, Inc., 2620 Augustine Dr. #245, Santa Clara, CA 95054, USA        *
 * or via info@compiere.org or http://www.compiere.org/license.html           *
 *****************************************************************************/
package org.adempiere.apps.form;

import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.VetoableChangeListener;
import java.sql.*;
import java.util.*;
import java.util.logging.*;
import java.io.File;
import java.math.*;

import javax.swing.*;
import javax.swing.table.*;

import org.adempiere.apps.SoundPlay;
import org.adempiere.model.MBarcodeTrx;
import org.adempiere.model.MBarcodeTrxLine;
import org.compiere.apps.*;
import org.compiere.apps.form.FormFrame;
import org.compiere.apps.form.FormPanel;
import org.compiere.grid.ed.*;
import org.compiere.minigrid.*;
import org.compiere.model.*;
import org.compiere.swing.*;
import org.compiere.util.*;
import org.jboss.util.Strings;
/**
 *  Barcode Transaction Form
 *
 *  @author  Shindu
 *  @version 1.2
 *  @since May 2013
 */


public class BarcodeTransaction extends CPanel
	implements FormPanel, ActionListener, VetoableChangeListener
{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 121224L;

	/**
	 *	Initialize Panel
	 *  @param WindowNo window
	 *  @param frame frame
	 */
	public void init (int WindowNo, FormFrame frame)
	{
		//
		log.info(frame.toString());
		p_WindowNo = WindowNo;
		m_frame = frame;
		m_frame.setMaximize(true);
		
		try
		{
			//
			MClientInfo info=MClientInfo.get(Env.getCtx());
			lenUPC=info.getUPC_Len();
			isCompleteBarcode=info.getIsCompleteDocAfterGenerateBarcode();
			//
			dynInit();
			parentInit();
			jbInit();			
			confirmPanel.addActionListener(this);
			confirmPanel.setOKVisible(false);
			delButton.setVisible(false);
			//  Set status
			statusBar.setStatusDB("");
			p_initOK = true;
		}
		catch(Exception e)
		{
			log.log(Level.SEVERE, "", e);
			p_initOK = false;
		}
	}	//	init
	
	/**
	 * Get Vendor only
	 * @throws Exception
	 */
	protected void initLookup () throws Exception
	{
		//  load BPartner
		int AD_Column_ID = 3795;// BPartner vendor/cust tergantung IsSOTrx
		MLookup lookup = MLookupFactory.get (Env.getCtx(), p_WindowNo, 0, AD_Column_ID, DisplayType.Search);
		bPartnerField = new VLookup ("C_BPartner_ID", true, false, true, lookup);
		//load doc type
		AD_Column_ID=3792;
		lookup = MLookupFactory.get(Env.getCtx(), p_WindowNo, 0, AD_Column_ID, DisplayType.Table);
		docTypeField=new VLookup("C_DocType_ID", true, false, true, lookup);
		//Locator		
		MLocatorLookup locator = new MLocatorLookup(Env.getCtx(), p_WindowNo);
		locatorField = new VLocator ("M_Locator_ID", true, false, true,	locator, p_WindowNo);		
		int M_Warehouse_ID = Env.getContextAsInt(Env.getCtx(), "M_Warehouse_ID");
		int M_Locator_ID =MWarehouse.get(Env.getCtx(), M_Warehouse_ID).getDefaultLocator().getM_Locator_ID();
		if (M_Locator_ID>0)
			locatorField.setValue(M_Locator_ID);
		//
				
	}   //  initBPartner
	
	/** Window No               */
	int      p_WindowNo;
	FormFrame 	m_frame;
	/** Model Tab               */
	//protected GridTab         		p_mTab;

	boolean p_initOK = false;
	boolean	isSOTrx=false;
	int totalLines;
	int totalScan;
	int lenUPC;
	boolean isCompleteBarcode=false;
	int C_Uom_ID;
	String UOM;
	//
	String resScannedInfo;
	protected int selectedIndex; //selected index in grid

	/** Loaded Order            */
	/**	Logger			*/
	CLogger 		log = CLogger.getCLogger(getClass());
	/**	Static Logger	*/
	//
	private CPanel parameterPanel = new CPanel();
	private BorderLayout parameterLayout = new BorderLayout();	
	private GridBagLayout parameterStdLayout = new GridBagLayout();
	private JScrollPane dataPane = new JScrollPane();
	private CPanel southPanel = new CPanel();
	private BorderLayout southLayout = new BorderLayout();
	private ConfirmPanel confirmPanel = new ConfirmPanel(true);	
	CButton delButton = new CButton(Env.getImageIcon2("Delete24"));
	//
	protected CPanel parameterStdPanel = new CPanel();
	protected MiniTable dataTable = new MiniTable();
	protected StatusBar statusBar = new StatusBar();
	//
	protected JLabel bPartnerLabel = new JLabel();	
	protected VLookup bPartnerField;
	protected JLabel locatorLabel = new JLabel();
	protected VLocator locatorField;
	protected JLabel docTypeLabel = new JLabel();
	protected VLookup docTypeField; 
	protected JLabel poReference = new JLabel();
	protected CTextField poReferenceField = new CTextField();
	protected JLabel barcodeLabel = new JLabel();
	protected CTextField barcodePN = new CTextField();
	protected JLabel infoInserted = new JLabel();
	//SOTrx Only
	protected JLabel cOrderLabel = new JLabel();	
	protected VLookup cOrderField;
	//Eceran only
	protected VNumber barcodeQty=new VNumber();
	protected JLabel barcodeQtyLabel = new JLabel();
	//
	protected VCheckBox isEceran = new VCheckBox();
	protected VCheckBox isGenerated = new VCheckBox();
	//
	protected Vector<Vector<Object>> data = new Vector<Vector<Object>>();
	//objmodel
	//protected MBarcodeTrx barcodetrx;
	protected int M_BarcodeTrx_ID;
	
	//MInOut iohdr;
    
	/**
	 *  Static Init
	 *  @throws Exception
	 */
	
	protected void jbInit() throws Exception
	{
		//Locator
        parameterStdPanel.add(locatorLabel, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0
                ,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 0, 5, 5), 0, 0));        
        parameterStdPanel.add(locatorField, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0
               ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 5, 5), 0, 0));        
        //Bpartner
       parameterStdPanel.add(bPartnerLabel, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0
                			,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
       parameterStdPanel.add(bPartnerField, new GridBagConstraints(3, 0, 1, 1, 0.0, 0.0
                				,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 5, 5), 0, 0));
        //Doc type       
       parameterStdPanel.add(docTypeLabel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0
   			,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(5, 5, 5, 5), 0, 0));
       parameterStdPanel.add(docTypeField, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0
   				,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 0, 5, 5), 0, 0));
		// Eceran
		parameterStdPanel.add(isEceran, new GridBagConstraints(2, 1, 1, 1, 0.0,
				0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL,
				new Insets(5, 0, 5, 5), 0, 0));
		//
		// PO ref
		parameterStdPanel.add(poReference, new GridBagConstraints(0, 3, 1, 1,
				0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE,
				new Insets(5, 0, 5, 5), 0, 0));
		parameterStdPanel.add(poReferenceField, new GridBagConstraints(1, 3, 1,
				1, 0.0, 0.0, GridBagConstraints.WEST,
				GridBagConstraints.HORIZONTAL, new Insets(5, 0, 5, 5), 0, 0));
		// barcode
		parameterStdPanel.add(barcodeLabel, new GridBagConstraints(0, 4, 1, 1,
				0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE,
				new Insets(5, 0, 5, 5), 0, 0));
		parameterStdPanel.add(barcodePN, new GridBagConstraints(1, 4, 1, 1,
				0.0, 0.0, GridBagConstraints.WEST,
				GridBagConstraints.HORIZONTAL, new Insets(5, 0, 5, 5), 0, 0));
		parameterStdPanel.add(infoInserted, new GridBagConstraints(2, 4, 3, 1,
				0.0, 0.0, GridBagConstraints.WEST,
				GridBagConstraints.HORIZONTAL, new Insets(5, 0, 5, 5), 0, 0));
		//
	}
	
	/**
	 *  Static Init
	 *  @throws Exception
	 */
	private void parentInit() throws Exception
	{		
		parameterPanel.setLayout(parameterLayout);
		parameterStdPanel.setLayout(parameterStdLayout);
		m_frame.getContentPane().add(parameterPanel, BorderLayout.NORTH);		
		//parameterPanel.add(parameterStdPanel, BorderLayout.CENTER);
		parameterPanel.add(parameterStdPanel, BorderLayout.WEST);
		//Data table
		dataPane.getViewport().add(dataTable, null);
	    dataTable.setRowSelectionAllowed(true);
	    dataTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
	    //
		
		delButton.setToolTipText("Delete selected line");
		delButton.addActionListener(this);
		delButton.setActionCommand("DeleteLine");
		confirmPanel.addButton(delButton);
		//
		barcodePN.setActionCommand("Barcode");
		barcodePN.addActionListener(this);
		poReferenceField.setActionCommand("POReference");
		poReferenceField.addActionListener(this);
		//
		m_frame.getContentPane().add(southPanel, BorderLayout.SOUTH);
		southPanel.setLayout(southLayout);
		southPanel.add(confirmPanel, BorderLayout.CENTER);
		m_frame.getContentPane().add(southPanel, BorderLayout.SOUTH);
		southPanel.setLayout(southLayout);
		southPanel.add(confirmPanel, BorderLayout.CENTER);
		southPanel.add(statusBar, BorderLayout.SOUTH);
		//
        m_frame.getContentPane().add(dataPane, BorderLayout.CENTER);
	}   //  parentInit

	/**
	 * 	Dispose
	 */
	public void dispose()
	{
		cancelBarcode();
		if (m_frame != null)
			m_frame.dispose();
		m_frame = null;		
	}	//	dispose

	/**
	 *  Dynamic Init (prepare dynamic fields)
	 *  @throws Exception if Lookups cannot be initialized
	 */
	protected void dynInit() throws Exception
	{
		
		log.config("");
		Font boldFont = new Font(getFont().getName(), Font.BOLD, 12);
		initLookup();
		locatorField.setMandatory(true);
		bPartnerField.setMandatory(true);
		docTypeField.setMandatory(true);
		//
		locatorLabel.setText(Msg.translate(Env.getCtx(), "M_Locator_ID"));
		bPartnerLabel.setText(Msg.translate(Env.getCtx(), "C_BPartner_ID"));
		docTypeLabel.setText(Msg.translate(Env.getCtx(), "C_DocType_ID"));
        //
        isGenerated.setText(Msg.translate(Env.getCtx(), "IsGeneratedInOut"));
        isGenerated.setReadWrite(false);
        isEceran.setText(Msg.translate(Env.getCtx(), "IsEceran"));
        isEceran.setReadWrite(false);
        //
        poReference.setText(Msg.translate(Env.getCtx(), "POReference"));
        poReferenceField.setMandatory(true);
        //
        barcodeLabel.setText("SCAN BARCODE");
        barcodeLabel.setFont(boldFont);
        barcodeLabel.setForeground(Color.BLUE);
        barcodePN.setFont(boldFont);
        barcodePN.setForeground(Color.BLUE);
        //
        Font fontInfo = new Font(getFont().getName(), Font.BOLD, 18);
        infoInserted.setForeground(Color.BLUE);
        infoInserted.setFont(fontInfo);
        //
        resetValue();
		//  Translation
		statusBar.setStatusLine("Ready");
		statusBar.setStatusDB("-");

	}   //  dynInit

	
	public void vetoableChange (PropertyChangeEvent e)
	{
		//	
		//
	}   //  vetoableChange
	
	/**
	 * Check input.
	 * @return error message
	 */
	protected String checkInput(){
		String errMsg=Strings.EMPTY;
		if (barcodePN.getValue().toString().length() < lenUPC) {			
			barcodePN.requestFocus();
			errMsg="Barcode invalid format!";
		} else if (locatorField.getValue() == null) {
			locatorField.requestFocus();
			errMsg="Locator is mandatory!";
		} else if (bPartnerField.getValue() == null) {			
			bPartnerField.requestFocus();
			errMsg="Business partner is mandatory!";
		} else if (docTypeField.getValue() == null) {
			docTypeField.requestFocus();
			errMsg="Document type is mandatory!";
		}
		return errMsg;
	}
	
	/**************************************************************************
	 *  Action Listener.
	 *  @param e event
	 */
	public void actionPerformed(ActionEvent e)
	{	
		if (e.getActionCommand().equalsIgnoreCase("Barcode")){
			infoInserted.setText("");
			String msg;
			msg=checkInput();//cek input			
			if (msg.equals(Strings.EMPTY)){ //tidak ada error
				msg=barcodeScan();
				if (msg.equals(Strings.EMPTY)){
					infoInserted.setText(resScannedInfo);
					// Revisi 2, tampilkan suara ketika barcode ok
					soundOK();
					// end revisi
					if (isSOTrx){
						statusBar.setStatusLine("Total lines: " + totalLines + " Total scan: " + totalScan); 
					}else
					{
						statusBar.setStatusLine("Total lines: " + totalLines);
					}					
					barcodeQty.setValue(Env.ZERO);
				}else{
					ADialog.beep();
					ADialog.error(p_WindowNo, this, "", msg);
					infoInserted.setText(msg);
				}
				barcodePN.requestFocus();
			}else
			{
				ADialog.beep();
				ADialog.warn(p_WindowNo, this, "", msg);
			}
			barcodePN.setText("");
		}else if (e.getActionCommand().equalsIgnoreCase("BarcodeEceran")){
			barcodeQty.requestFocus();
		}else if (e.getActionCommand().equalsIgnoreCase("POReference")){
			barcodePN.requestFocus();
		}else if (e.getActionCommand().equalsIgnoreCase("DeleteLine")){
			if (ADialog.ask(p_WindowNo, this,"","Delete selected line?" )){
				deleteLine();
				barcodePN.requestFocus();
				if (isSOTrx){
					statusBar.setStatusLine("Total lines: " + totalLines + " Total scan: " + totalScan); 
				}else
				{
					statusBar.setStatusLine("Total lines: " + totalLines);
				}
			}			
		}else if(e.getActionCommand().equals(ConfirmPanel.A_OK)){
			generatMinOut();
			statusBar.setStatusLine("Ready!");
		}else if(e.getActionCommand().equals(ConfirmPanel.A_CANCEL)){
			if (ADialog.ask(p_WindowNo, this,"Close","Are you sure?" )){
				//do cancel barcode on dispose. See dispose()
				dispose();
			}			
		}else{
			//System.out.println("Barcode Scan.Other action: " +  e.getActionCommand());
		}
	}   //  actionPerformed
	
	/**
	 * Reset field after save
	 */
	protected void resetValue(){
		barcodePN.setText("");
		poReferenceField.setText("");
		infoInserted.setText("Ready");
		isEceran.setSelected(false);
		isGenerated.setSelected(false);		
		totalLines=0;
		totalScan=0;
		M_BarcodeTrx_ID=0;
	}
	
	private String[] parseBarcode(String BarcodeText){
		BarcodeText=BarcodeText.trim();
		String [] result = new String[2];
		result[0]=BarcodeText.substring(0, lenUPC);
		result[1]=BarcodeText.substring(lenUPC);
		return result;
	}
	
		
	/**
	 * Do barcode scan
	 * @return
	 */
	private String barcodeScan() {				
		// Get produk
		String result = "";
		String[] barcode = parseBarcode(barcodePN.getText());
		if (barcode[1] == null)
			return "Invalid barcode string";
		BigDecimal qty;
		try{
			if (isEceran.isSelected() && isSOTrx){
				qty= (BigDecimal) barcodeQty.getValue();
				barcode[1]= qty.toPlainString();
			}
			else
				qty= new BigDecimal(barcode[1]);
			if (qty.compareTo(Env.ONE)==-1)
				throw new Exception();
		}catch(Exception ex){
			return "Invalid barcode string";
		}
		//cek tambahan barcode
		result=barcodeValidation(barcode); 
		if (!result.equals(Strings.EMPTY)){
			return result;
		}
		//
		result=Strings.EMPTY;
		infoInserted.setText("");
		
		String sql = "SELECT M_Product_ID FROM M_Product WHERE UPC = ?";
		int M_Product_ID = 0;
		try {
			PreparedStatement pstmt = DB.prepareStatement(sql, null);
			pstmt.setString(1, barcode[0]);
			ResultSet rs = pstmt.executeQuery();
			if (rs.next())
				M_Product_ID = rs.getInt(1);
			rs.close();
			pstmt.close();
			if (M_Product_ID == 0)
				result = "Product not found";
		} catch (SQLException e) {
			log.log(Level.SEVERE, sql.toString(), e);
			result = "Product not found";
		}
		if (!result.equals(Strings.EMPTY))
			return result;

		Trx trx = Trx.get(Trx.createTrxName(), true);
		//setelah ini tidak boleh ada return		
		if (!confirmPanel.isOKVisible()) {
			MBarcodeTrx barcodetrx;
			barcodetrx = new MBarcodeTrx(Env.getCtx(), 0, trx.getTrxName());
			barcodetrx.setC_DocType_ID((Integer) docTypeField.getValue());
			barcodetrx.setC_BPartner_ID((Integer) bPartnerField.getValue());
			barcodetrx.setIsSOTrx(isSOTrx);
			barcodetrx.setScanDate(TimeUtil.getServerTime());
			barcodetrx.setM_Locator_ID((Integer) locatorField.getValue());
			barcodetrx.setIsGeneratedToInOut(false);
			barcodetrx.setIsEceran(isEceran.isSelected());
			barcodetrx.setPOReference(poReferenceField.getText());
			if (isSOTrx){
				barcodetrx.setC_Order_ID((Integer) cOrderField.getValue());
			}					
			barcodetrx.save();			
			enableHeader(false);
			M_BarcodeTrx_ID=barcodetrx.get_ID();
			//
		}
		//
		MProduct prd = MProduct.get(Env.getCtx(), M_Product_ID);		
		if (prd != null){
			try{
				C_Uom_ID=prd.getC_UOM().getC_UOM_ID();
				UOM = prd.getC_UOM().getUOMSymbol();
			}catch (Exception ex){
				result= "UOM Error";
			}		
		}else
			result= Msg.getMsg(Env.getCtx(), "UOM not found");		
		//		
		MBarcodeTrxLine barcodeLine = new MBarcodeTrxLine(Env.getCtx(), 0,
				M_BarcodeTrx_ID, trx.getTrxName());
		barcodeLine.setC_UOM_ID(C_Uom_ID);
		barcodeLine.setQty(qty); 
		barcodeLine.setM_Product_ID(M_Product_ID);
		if (isSOTrx) //set OrderLine
			barcodeLine.setC_OrderLine_ID((Integer) dataTable.getModel().getValueAt(selectedIndex, 0));//Hardcode get SO Line
		barcodeLine.save();
		//
		if (isSOTrx){
			result = updateLine(selectedIndex,qty.doubleValue());
		}else
		{
			addLine(barcodeLine.get_ID(), barcode[0], M_Product_ID, prd.getName(), qty.doubleValue());
			//infoInserted.setText(Msg.getMsg(Env.getCtx(), "Inserted"));
		}
		if(result.equals(Strings.EMPTY)){
			trx.commit();
		}
		else
			trx.rollback();
		trx.close();
		if (isEceran.isSelected()){
			resScannedInfo=prd.getName() + " Qty: " + qty.intValue();
		}else{
			resScannedInfo=prd.getName() + " Qty: " + qty.toPlainString();
		}
		
		return result;		
	}
	/**
	 * Pengecekan tambahan.
	 * Bisa diturunkan
	 * @return
	 */
	protected String barcodeValidation(String[] barcode){
		return Strings.EMPTY;
	}

	/**
	 * Enable header
	 * @param enabled
	 */
	protected void enableHeader(boolean enabled){	
		locatorField.setReadWrite(enabled);
		bPartnerField.setReadWrite(enabled);
		docTypeField.setReadWrite(enabled);
		poReferenceField.setReadWrite(enabled);
		//
		confirmPanel.setOKVisible(!enabled);
		delButton.setVisible(!enabled);
		
	}
	
	/**
	 * Add data for Material Receipt transaction
	 * @param PartNumber
	 * @param MProductID
	 * @param ProductName
	 * @param qty
	 */
	private void addLine(int BarocdeLineID, String PartNumber, int MProductID, String ProductName,
			double qty) {
		Vector<Object> line = new Vector<Object>(5);
		line.add(BarocdeLineID); // 0-ID
		line.add(PartNumber); // 1-VendorProductNo
		KeyNamePair pp = new KeyNamePair(MProductID, ProductName);
		line.add(pp); // 2-Product
		line.add(qty); // 3-Qty
		pp = new KeyNamePair(C_Uom_ID, UOM);
		line.add(pp); // 4-UOM		
		data.add(line);
		//
		loadTableOIS(data);
		totalLines++;
		try {
			dataTable.scrollRectToVisible(dataTable.getCellRect(totalLines-1, 0, true));
		}catch(Exception ex){
			System.out.println(ex.getMessage());
		}	
		dataTable.getSelectionModel().setSelectionInterval(totalLines-1, totalLines-1);
	}
	
	/**
	 * UPdate data method 2. Direct update grid
	 * @param index to update
	 * @param scanned qty
	 */
	protected String updateLine(int index, double scanned) {
		return Strings.EMPTY;	   
	}
	
	/**
	 * Delete barcode transaction line 
	 */
	protected void deleteLine(){			
		if (totalLines<1){
			ADialog.warn(p_WindowNo, this, "NoLines");
			return;
		}
		
		if (dataTable.getSelectedRowCount()<1){	
			ADialog.warn(p_WindowNo, this, "No selected line");
			return;
		}		
		Trx trx = Trx.get(Trx.createTrxName(), true);
		/**delete lines **/
		int M_BarcodeTrxLine_ID= (Integer) dataTable.getValueAt(dataTable.getSelectedRow(), 0); //get id
		MBarcodeTrxLine line = new MBarcodeTrxLine(Env.getCtx(), M_BarcodeTrxLine_ID, trx.getTrxName());
		boolean isOK=line.delete(true);
		trx.commit();
		trx.close();		
		if (isOK){
			DefaultTableModel tmpData= (DefaultTableModel) dataTable.getModel();
			tmpData.removeRow(dataTable.getSelectedRow());
			totalLines--;
		}else{
			ADialog.warn(p_WindowNo, this,"", "Error delete line.");
		}
	}
		
	private void loadTableOIS(Vector<Vector<Object>> data) {
		//  Header Info
		    Vector<String> columnNames = new Vector<String>(4);
		    columnNames.add("id");
		    columnNames.add(Msg.getElement(Env.getCtx(), "UPC", false));
		    columnNames.add(Msg.translate(Env.getCtx(), "M_Product_ID"));		    
		    columnNames.add(Msg.translate(Env.getCtx(), "Quantity"));		    
		    columnNames.add("UOM");		    
		    //  Set Model
		    DefaultTableModel model = new DefaultTableModel(data, columnNames);		    
		    //
		    dataTable.setModel(model);
		    //		    
		    dataTable.setColumnClass(0, Integer.class, true);        // 0-Index
		    dataTable.setColumnVisibility(dataTable.getColumn("id"), false); //invisible
		    dataTable.setColumnClass(1, String.class, true);        //  1-UPC
		    dataTable.setColumnClass(2, String.class, true);        //  2-Product
		    dataTable.setColumnClass(3, Double.class, true);        //  3-Qty
		    dataTable.setColumnClass(4, String.class, true);        //  4-UOm		    
		    dataTable.autoSize();
		}
	
	/**
	 * generate MInOut
	 */
	private void generatMinOut()
	{
		if (totalLines<1){
			ADialog.warn(p_WindowNo, this, "NoLines");
			return;
		}				
		if (!ADialog.ask(p_WindowNo, this,"SaveChanges?" )){
			return;
		}
		if (M_BarcodeTrx_ID==0){
			ADialog.warn(p_WindowNo, this, "NoData");
			return;
		}
		String errormsg=Strings.EMPTY;
		Trx trx = Trx.get(Trx.createTrxName(), true);
		MBarcodeTrx barcodetrx = new MBarcodeTrx(Env.getCtx(), M_BarcodeTrx_ID, trx.getTrxName());
		MInOut result = barcodetrx.generateMInOut(isCompleteBarcode);
		errormsg=CLogger.retrieveErrorString("");
		//trx.commit();
		trx.close();
		if (result != null) {
			String status;
			if(result.getDocStatus()==MInOut.STATUS_Completed)
				status = "Complete";
			else
				status = "Not Complete";
			ADialog.info(p_WindowNo, this, "", (isSOTrx ? "Shipment "
					: "Receipt ")
					+ "generated: "
					+ result.getDocumentNo() + " with status " + status 
					+ "\r\nBarcode: " + barcodetrx.getM_BarcodeTrx_ID());
			enableHeader(true);
			resetValue();
			data.clear();
			loadTableOIS(data);
		}else{
			ADialog.warn(p_WindowNo, this, "","Generate shipment failed!\r\n" + errormsg);
		}
		
	}
	
	/***
	 * Cancel Barcode
	 */
	private void cancelBarcode()
	{
		//jika blm ada barcode trx, maka ga melakukan apa2
		if (M_BarcodeTrx_ID==0)
			return;
		//
		Trx trx = Trx.get(Trx.createTrxName(), true);
		MBarcodeTrx barcodetrx = new MBarcodeTrx(Env.getCtx(), M_BarcodeTrx_ID, trx.getTrxName());
		boolean result = barcodetrx.cancelBarcode();
		if (result)
			trx.commit();
		else
			trx.rollback();
		trx.close();
	}
	
	/**
	 * Play sound saat barcode ok
	 * Paket revisi 2, 14 Dec 2013
	 */
	private void soundOK()
	{
		String fileUrl = System.getProperty("user.home") + File.separatorChar + "barcode_ok.wav";
		try {
			File soundFile = new File(fileUrl);
			if (!soundFile.canRead())
			{
				soundFile=null;
				fileUrl=Strings.EMPTY;
			}
		} catch (Exception e) {
			fileUrl=Strings.EMPTY;
		}
		if (fileUrl.equals(Strings.EMPTY))
			return;
		SoundPlay.playSound(fileUrl);
	
	}
	
}


